package service

import (
	"context"
	"encoding/json"
	"fmt"
	"math/rand"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/config"
	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/middleware"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/common"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay"
	photonpayservices "gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay/services"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// PlatformSwitchService 平台切换服务
type PlatformSwitchService struct {
	db *gorm.DB
}

// NewPlatformSwitchService 创建平台切换服务实例
func NewPlatformSwitchService() *PlatformSwitchService {
	return &PlatformSwitchService{
		db: database.DB,
	}
}

// CheckSwitchConstraints 检查平台切换约束
func (s *PlatformSwitchService) CheckSwitchConstraints(ctx context.Context, userID int64) (*models.SwitchConstraint, error) {
	// 获取用户的活跃矩阵账户信息
	var matrixAccount models.UserMatrixAccount
	if err := s.db.Where("user_id = ? AND status = 'active'", userID).First(&matrixAccount).Error; err != nil {
		return nil, fmt.Errorf("找不到用户的活跃矩阵账户: %v", err)
	}

	constraints := &models.SwitchConstraint{}

	// 1. 检查卡片数据约束
	var cardCount int64
	if err := s.db.Model(&models.UserCard{}).
		Where("user_id = ? AND platform = ?", userID, matrixAccount.PlatformType).
		Count(&cardCount).Error; err != nil {
		return nil, fmt.Errorf("检查卡片数据失败: %v", err)
	}
	constraints.HasCards = cardCount > 0

	// 2. 检查管理员转账记录约束
	var adminTransferCount int64
	if err := s.db.Model(&models.AdminTransferRecord{}).
		Where("platform_account = ? AND status IN ?", matrixAccount.MatrixAccount, []string{"pending", "success"}).
		Count(&adminTransferCount).Error; err != nil {
		return nil, fmt.Errorf("检查管理员转账记录失败: %v", err)
	}
	constraints.HasAdminTransfers = adminTransferCount > 0

	// 3. 检查子账号数据约束
	var subAccountCount int64
	if err := s.db.Model(&models.SubAccount{}).
		Where("user_id = ? AND balance > 0", userID).
		Count(&subAccountCount).Error; err != nil {
		return nil, fmt.Errorf("检查子账号数据失败: %v", err)
	}
	constraints.HasSubAccounts = subAccountCount > 0

	// 4. 检查主账号数据约束
	var masterAccountCount int64
	if err := s.db.Model(&models.MasterAccount{}).
		Where("user_id = ? AND balance > 0", userID).
		Count(&masterAccountCount).Error; err != nil {
		return nil, fmt.Errorf("检查主账号数据失败: %v", err)
	}
	constraints.HasMasterAccount = masterAccountCount > 0

	// 5. 检查子矩阵账户约束（只检查活跃状态的）
	var childAccountCount int64
	if err := s.db.Model(&models.UserMatrixAccount{}).
		Where("parent_matrix_account_id = ? AND status = 'active'", matrixAccount.ID).
		Count(&childAccountCount).Error; err != nil {
		return nil, fmt.Errorf("检查子矩阵账户失败: %v", err)
	}
	constraints.HasChildAccounts = childAccountCount > 0

	// 判断是否可以切换
	constraints.CanSwitch = !constraints.HasCards &&
		!constraints.HasAdminTransfers &&
		!constraints.HasSubAccounts &&
		!constraints.HasMasterAccount &&
		!constraints.HasChildAccounts

	// 生成约束原因
	if !constraints.CanSwitch {
		var reasons []string
		if constraints.HasCards {
			reasons = append(reasons, "存在卡片数据")
		}
		if constraints.HasAdminTransfers {
			reasons = append(reasons, "存在管理员转账记录")
		}
		if constraints.HasSubAccounts {
			reasons = append(reasons, "存在子账号余额")
		}
		if constraints.HasMasterAccount {
			reasons = append(reasons, "存在主账号余额")
		}
		if constraints.HasChildAccounts {
			reasons = append(reasons, "存在子矩阵账户")
		}
		constraints.Reason = fmt.Sprintf("无法切换平台，原因：%s", reasons[0])
	}

	return constraints, nil
}

// ExecutePlatformSwitch 执行平台切换
func (s *PlatformSwitchService) ExecutePlatformSwitch(ctx context.Context, userID int64, targetPlatform string, reason string, operatorID *int64) (*models.PlatformSwitchResponse, error) {
	// 验证目标平台是否支持
	if !models.IsSupportedPlatform(targetPlatform) {
		return nil, fmt.Errorf("不支持的目标平台: %s", targetPlatform)
	}

	// 获取用户的活跃矩阵账户信息
	var matrixAccount models.UserMatrixAccount
	if err := s.db.Where("user_id = ? AND status = 'active'", userID).First(&matrixAccount).Error; err != nil {
		return nil, fmt.Errorf("找不到用户的活跃矩阵账户: %v", err)
	}

	// 检查目标平台是否与当前平台相同
	if matrixAccount.PlatformType == targetPlatform {
		return nil, fmt.Errorf("目标平台与当前平台相同")
	}

	// 再次检查约束条件
	constraints, err := s.CheckSwitchConstraints(ctx, userID)
	if err != nil {
		return nil, fmt.Errorf("检查约束条件失败: %v", err)
	}

	if !constraints.CanSwitch {
		return nil, fmt.Errorf("无法切换平台: %s", constraints.Reason)
	}

	// 使用事务执行平台切换
	var response *models.PlatformSwitchResponse
	err = s.db.Transaction(func(tx *gorm.DB) error {
		oldPlatform := matrixAccount.PlatformType

		// 1. 冻结旧的矩阵账户记录
		if err := tx.Model(&matrixAccount).Update("status", "frozen").Error; err != nil {
			return fmt.Errorf("冻结旧矩阵账户失败: %v", err)
		}

		// 2. 检查目标平台是否已有矩阵账户记录
		var existingMatrixAccount models.UserMatrixAccount
		err = tx.Where("user_id = ? AND platform_type = ?", userID, targetPlatform).First(&existingMatrixAccount).Error

		if err != nil && err != gorm.ErrRecordNotFound {
			return fmt.Errorf("检查目标平台矩阵账户失败: %v", err)
		}

		if err == gorm.ErrRecordNotFound {
			// 目标平台没有矩阵账户记录，需要创建
			var newMatrixAccountNo string

			switch targetPlatform {
			case "photonpay":
				// PhotonPay平台：调用API创建矩阵账户
				newMatrixAccountNo, err = s.createPhotonPayMatrixAccount(ctx, matrixAccount.MatrixAccountName)
				if err != nil {
					return fmt.Errorf("创建PhotonPay矩阵账户失败: %v", err)
				}
			case "hlpay":
				// HlPay平台：本地生成矩阵账户号
				newMatrixAccountNo, err = s.generateHlPayMatrixAccount()
				if err != nil {
					return fmt.Errorf("生成HlPay矩阵账户号失败: %v", err)
				}
			default:
				return fmt.Errorf("不支持的平台类型: %s", targetPlatform)
			}

			// 创建新的矩阵账户记录
			newMatrixAccount := models.UserMatrixAccount{
				UserID:                matrixAccount.UserID,
				MatrixAccount:         newMatrixAccountNo,
				MatrixAccountName:     matrixAccount.MatrixAccountName,
				PlatformType:          targetPlatform,
				Status:                "active",
				TotalTransferAmount:   matrixAccount.TotalTransferAmount,
				ParentMatrixAccountID: matrixAccount.ParentMatrixAccountID,
			}

			if err := tx.Create(&newMatrixAccount).Error; err != nil {
				return fmt.Errorf("创建新矩阵账户失败: %v", err)
			}

			// 如果是HlPay平台，创建对应的余额记录
			if targetPlatform == "hlpay" {
				hlPayBalance := &models.HlPayAccountBalance{
					AccountNo:       fmt.Sprintf("HL-USD%d", time.Now().UnixNano()),
					Currency:        "USD",
					MemberID:        fmt.Sprintf("%d", userID),
					OwnerNo:         newMatrixAccountNo,
					OwnerType:       "matrix",
					RealTimeBalance: decimal.NewFromFloat(0),
					Status:          "active",
				}

				if err := tx.Create(hlPayBalance).Error; err != nil {
					return fmt.Errorf("创建HlPay账户余额记录失败: %v", err)
				}
			}
		} else {
			// 目标平台已有矩阵账户记录，直接激活
			if err := tx.Model(&existingMatrixAccount).Update("status", "active").Error; err != nil {
				return fmt.Errorf("激活目标平台矩阵账户失败: %v", err)
			}
		}

		// 3. 冻结当前活跃的矩阵账户
		if err := tx.Model(&matrixAccount).Update("status", "frozen").Error; err != nil {
			return fmt.Errorf("冻结当前矩阵账户失败: %v", err)
		}

		// 4. 记录切换日志
		// 将约束检查结果转换为JSON字符串
		constraintCheckResult := &models.ConstraintCheckResult{
			HasCards:          constraints.HasCards,
			HasAdminTransfers: constraints.HasAdminTransfers,
			HasSubAccounts:    constraints.HasSubAccounts,
			HasMasterAccount:  constraints.HasMasterAccount,
			HasChildAccounts:  constraints.HasChildAccounts,
			CanSwitch:         constraints.CanSwitch,
			Reason:            constraints.Reason,
		}

		// 手动序列化为JSON字符串
		constraintCheckJSON, err := json.Marshal(constraintCheckResult)
		if err != nil {
			return fmt.Errorf("序列化约束检查结果失败: %v", err)
		}

		switchLog := &models.PlatformSwitchLog{
			UserID:                userID,
			OldPlatform:           oldPlatform,
			NewPlatform:           targetPlatform,
			SwitchReason:          &reason,
			OperatorID:            operatorID,
			ConstraintCheckResult: string(constraintCheckJSON),
			Status:                "success",
		}

		if err := tx.Create(switchLog).Error; err != nil {
			return fmt.Errorf("创建切换日志失败: %v", err)
		}

		// 5. 清除相关缓存
		s.clearUserCache(userID)

		// 6. 构建响应
		response = &models.PlatformSwitchResponse{
			OldPlatform: oldPlatform,
			NewPlatform: targetPlatform,
			SwitchedAt:  time.Now(),
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return response, nil
}

// GetSwitchLogs 获取平台切换日志
func (s *PlatformSwitchService) GetSwitchLogs(ctx context.Context, userID int64, page, pageSize int) ([]models.PlatformSwitchLog, int64, error) {
	var logs []models.PlatformSwitchLog
	var total int64

	// 获取总数
	if err := s.db.Model(&models.PlatformSwitchLog{}).
		Where("user_id = ?", userID).
		Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("获取日志总数失败: %v", err)
	}

	// 分页查询
	if err := s.db.Where("user_id = ?", userID).
		Order("created_at DESC").
		Offset((page-1)*pageSize).
		Limit(pageSize).
		Preload("User", func(db *gorm.DB) *gorm.DB {
			return db.Select("id, username, email")
		}).
		Preload("Operator", func(db *gorm.DB) *gorm.DB {
			return db.Select("id, username, email")
		}).
		Find(&logs).Error; err != nil {
		return nil, 0, fmt.Errorf("获取切换日志失败: %v", err)
	}

	return logs, total, nil
}

// GetUserPlatformAccounts 获取用户的所有平台账户状态
func (s *PlatformSwitchService) GetUserPlatformAccounts(ctx context.Context, userID int64) ([]models.UserMatrixAccount, error) {
	var accounts []models.UserMatrixAccount

	if err := s.db.Where("user_id = ?", userID).
		Order("platform_type ASC, created_at DESC").
		Find(&accounts).Error; err != nil {
		return nil, fmt.Errorf("获取用户平台账户失败: %v", err)
	}

	return accounts, nil
}

// createPhotonPayMatrixAccount 创建PhotonPay矩阵账户
func (s *PlatformSwitchService) createPhotonPayMatrixAccount(ctx context.Context, matrixAccountName string) (string, error) {
	// 创建PhotonPay客户端
	platformConfig := &common.PlatformConfig{
		AppID:      config.GlobalConfig.PhotonPay.AppID,
		AppSecret:  config.GlobalConfig.PhotonPay.AppSecret,
		GatewayURL: config.GlobalConfig.PhotonPay.GatewayURL,
	}
	client := photonpay.NewPhotonPayClient(platformConfig)

	// 准备创建矩阵账户的请求体
	requestBody := map[string]interface{}{
		"matrixAccountName": matrixAccountName,
	}

	bodyBytes, err := json.Marshal(requestBody)
	if err != nil {
		return "", fmt.Errorf("准备矩阵账户创建请求失败: %v", err)
	}

	// 调用PhotonPay API创建矩阵账户
	resp, err := photonpayservices.CreateMatrixAccount(ctx, client, bodyBytes)
	if err != nil {
		return "", fmt.Errorf("创建矩阵账户失败: %v", err)
	}

	// 解析响应获取矩阵账户号
	var matrixAccountResp struct {
		Code string `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			MatrixAccount string `json:"matrixAccount"`
		} `json:"data"`
	}

	if err := json.Unmarshal(resp, &matrixAccountResp); err != nil {
		return "", fmt.Errorf("解析矩阵账户响应失败: %v", err)
	}

	if matrixAccountResp.Code != "0000" {
		return "", fmt.Errorf("创建矩阵账户失败: %s", matrixAccountResp.Msg)
	}

	return matrixAccountResp.Data.MatrixAccount, nil
}

// generateHlPayMatrixAccount 生成HlPay矩阵账户号
func (s *PlatformSwitchService) generateHlPayMatrixAccount() (string, error) {
	// HlPay平台：生成HL前缀的矩阵账户
	timestamp := time.Now().UnixMilli()
	randomNum := rand.Intn(100000)
	return fmt.Sprintf("HL%d%05d", timestamp, randomNum), nil
}

// clearUserCache 清除用户相关缓存
func (s *PlatformSwitchService) clearUserCache(userID int64) {
	// 清除平台信息缓存
	middleware.ClearPlatformInfoCache(userID)

	// 清除矩阵账户缓存
	middleware.ClearMatrixAccountCache(userID)

	// 清除所有平台信息缓存（确保完全清除）
	middleware.ClearAllPlatformInfoCache()
}
